﻿using System;

namespace Mates
{
    public static class Funcions
    {
        public const float Pi = 3.14159265f;
        public const float TwoPi = Pi * 2; //360º
        public const float PowPi = Pi * Pi;
        public const float FourPi = Pi * 4;
        public const float HalfPi = Pi / 2; //90º
        public const float PiO3 = Pi / 3; //60º
        public const float PiO4 = Pi / 4; //45º
        public const float PiO6 = Pi / 6;//30º
        public const float e = 2.718281828f;

        /// <summary>
        /// Desbordem radians amb límit -PI/PI, retorna Randians en format float
        /// </summary>
        /// <param name="radians"></param>
        public static float WrapAngle(float radians)
        {
            while (radians < -Pi)
            {
                radians += TwoPi;
            }
            while (radians > Pi)
            {
                radians -= TwoPi;
            }
            return radians;
        }
        /// <summary>
        /// Desbordem number amb límit max
        /// </summary>
        /// <param name="number"></param>
        /// <param name="max"></param>
        public static int Wrap(int number, int max)
        {
            int wrap = number % max;
            if (wrap < 0)
                wrap += max;
            return wrap;
        }
        /// <summary>
        /// Tornem 0 si number es negatiu
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static int MTZ(int number)
        {
            if (number <= 0)
                return 0;
            else
                return number;            
        }
        /// <summary>
        /// Tornem 0 si number es negatiu
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static float MTZ(float number)
        {
            if (number <= 0)
                return 0;
            else
                return number;
        }
        /// <summary>
        /// Flatten Array 3D > 1D 
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static int A3DToFlat(int x, int y, int z, int xMax, int yMax, int zMax)
        {
            return (x * xMax * yMax + y * zMax + z);
        }
        /// <summary>
        /// Flatten Array 2D > 1D 
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static int A2DToFlat(int x, int y, int xMax)
        {
            return (x * xMax + y);
        }

        /// <summary>
        /// Clamp (int, float i double)
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static int Clamp(int value, int min, int max)
        {
            if (value < min)
                value = min;
            if (value > max)
                value = max;
            return value;
        }
        /// <summary>
        /// MinMax (int, float i double)
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>

        public static float Clamp(float value, float min, float max)
        {
            if (value < min)
                value = min;
            if (value > max)
                value = max;
            return value;
        }
        /// <summary>
        /// MinMax (int, float i double)
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>

        public static double Clamp(double value, double min, double max)
        {
            if (value < min)
                value = min;
            if (value > max)
                value = max;
            return value;
        }

        /// <summary>
        /// Conversió Radians<->Graus
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>

        public static float Rad2Deg(float radians)
        {
            return (radians * 57.29578f);
        }
        /// <summary>
        /// Conversió Radians<->Graus
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>

        public static float Deg2Rad(float degrees)
        {
            return (degrees * 0.01745329f);
        }


        /// <summary>
        /// Mod, evita 0div
        /// </summary>
        public static float Mod(float value, float divider)
        {
            if (divider == 0f)
            {
                return value;
            }
            return (value % divider);
        }
        /// <summary>
        /// Mod, evita 0div
        /// </summary>
        public static int Mod(int value, int divider)
        {
            if (divider == 0f)
            {
                return value;
            }
            return (value % divider);
        }

        // <summary>
        // Sign, retorna true en diferència de signe
        // retorna true en cas de ser negatiu
        // </summary>
        public static bool Sign(float a, float b)
        {
            if((a > 0) && (b < 0))
                return true;
            if((a < 0) && (b > 0))
                return true;
            return false;
        }
        public static bool Sign(float a)
        {
            return a < 0 ? true : false;
        }
        public static bool Sign(double a)
        {
            return a < 0 ? true : false;
        }



    }

}
